/*
 * MiniPadView.java
 * just modified...
 */

//TODO vérifier quand on select par le bouton shift du clavier
package minipad;

import Controleur.Controleur;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;

//added
import javax.swing.text.*;

/**
 * The application's main frame.
 */
public class MiniPadView extends FrameView implements GetViewInterface,UpdateViewReceiver{

    private Modele.PressePapier pp = Modele.PressePapier.getInstance();
    private InternalViewData data = InternalViewData.getInstance(this);
    private Controleur ctrl = new Controleur(this);

    public MiniPadView(SingleFrameApplication app) {
        super(app);


        initComponents();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
//                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
//                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
//        statusAnimationLabel.setIcon(idleIcon);
//        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
//                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
//                    progressBar.setVisible(true);
//                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
//                    statusAnimationLabel.setIcon(idleIcon);
//                    progressBar.setVisible(false);
//                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
//                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
//                    progressBar.setVisible(true);
//                    progressBar.setIndeterminate(false);
//                    progressBar.setValue(value);
                }
            }
        });

        data.setCaret(texte.getCaret());
//        ctrl.setUvr(this);
        ctrl.setgvi(this);

        updateGUI();

    }

    protected void SetText(String s) {
        texte.setText(s);
    }

    protected void setPressePapier(String s){
        pp.setBuffer(s);
    }

    protected void setCaret(Caret c) {
        texte.setCaret(c);
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = MiniPadApp.getApplication().getMainFrame();
            aboutBox = new MiniPadAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        MiniPadApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        JPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        texte = new javax.swing.JTextArea();
        btn_undo = new javax.swing.JButton();
        btn_redo = new javax.swing.JButton();
        btnStart = new javax.swing.JButton();
        btnStop = new javax.swing.JButton();
        btnPlay = new javax.swing.JButton();
        btn_cut = new javax.swing.JButton();
        btn_copy = new javax.swing.JButton();
        btn_coller = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();

        JPanel.setName("JPanel"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        texte.setColumns(20);
        texte.setEditable(false);
        texte.setRows(5);
        texte.setName("texte"); // NOI18N
        texte.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                texteMouseReleased(evt);
            }
        });
        texte.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                texteKeyTyped(evt);
            }
        });
        jScrollPane1.setViewportView(texte);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(minipad.MiniPadApp.class).getContext().getActionMap(MiniPadView.class, this);
        btn_undo.setAction(actionMap.get("Undo_click")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(minipad.MiniPadApp.class).getContext().getResourceMap(MiniPadView.class);
        btn_undo.setText(resourceMap.getString("btn_undo.text")); // NOI18N
        btn_undo.setName("btn_undo"); // NOI18N

        btn_redo.setAction(actionMap.get("redo_click")); // NOI18N
        btn_redo.setText(resourceMap.getString("btn_redo.text")); // NOI18N
        btn_redo.setName("btn_redo"); // NOI18N

        btnStart.setText(resourceMap.getString("btnStart.text")); // NOI18N
        btnStart.setName("btnStart"); // NOI18N
        btnStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnStartActionPerformed(evt);
            }
        });

        btnStop.setAction(actionMap.get("StopRecord_click")); // NOI18N
        btnStop.setText(resourceMap.getString("btnStop.text")); // NOI18N
        btnStop.setName("btnStop"); // NOI18N

        btnPlay.setAction(actionMap.get("Replay_click")); // NOI18N
        btnPlay.setText(resourceMap.getString("btnPlay.text")); // NOI18N
        btnPlay.setName("btnPlay"); // NOI18N

        btn_cut.setAction(actionMap.get("Cut_click")); // NOI18N
        btn_cut.setName("btn_cut"); // NOI18N

        btn_copy.setAction(actionMap.get("Copy_click")); // NOI18N
        btn_copy.setName("btn_copy"); // NOI18N

        btn_coller.setAction(actionMap.get("Paste_click")); // NOI18N
        btn_coller.setName("btn_coller"); // NOI18N

        javax.swing.GroupLayout JPanelLayout = new javax.swing.GroupLayout(JPanel);
        JPanel.setLayout(JPanelLayout);
        JPanelLayout.setHorizontalGroup(
            JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(JPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 365, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(JPanelLayout.createSequentialGroup()
                        .addComponent(btn_undo)
                        .addGap(60, 60, 60)
                        .addComponent(btn_redo))
                    .addGroup(JPanelLayout.createSequentialGroup()
                        .addGroup(JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(JPanelLayout.createSequentialGroup()
                                .addComponent(btnStart)
                                .addGap(18, 18, 18)
                                .addComponent(btnStop))
                            .addGroup(JPanelLayout.createSequentialGroup()
                                .addComponent(btn_cut)
                                .addGap(18, 18, 18)
                                .addComponent(btn_copy)))
                        .addGap(18, 18, 18)
                        .addGroup(JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(btn_coller)
                            .addComponent(btnPlay))))
                .addContainerGap(25, Short.MAX_VALUE))
        );
        JPanelLayout.setVerticalGroup(
            JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(JPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btn_undo)
                    .addComponent(btn_redo))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnStart)
                    .addComponent(btnStop)
                    .addComponent(btnPlay))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(JPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btn_cut)
                    .addComponent(btn_copy)
                    .addComponent(btn_coller))
                .addContainerGap(22, Short.MAX_VALUE))
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        setComponent(JPanel);
        setMenuBar(menuBar);
    }// </editor-fold>//GEN-END:initComponents

    private void texteKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_texteKeyTyped

        int pos = texte.getCaretPosition();
//        evt.consume();

        Character c = new Character(evt.getKeyChar());

        if (Character.isLetterOrDigit(c) || c.equals(' ') || c.equals('\n')) {
            data.setLastChar(c);
            data.setCaretPos(texte.getCaretPosition());

            ctrl.inserer();
        } else if (c==evt.VK_BACK_SPACE){
            data.setCaretPos(texte.getCaretPosition());
            ctrl.delete();
        }

    }//GEN-LAST:event_texteKeyTyped

    private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartActionPerformed
        data.setMacroEnabled(true);
        updateGUI();
    }//GEN-LAST:event_btnStartActionPerformed

    private void texteMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_texteMouseReleased

        //On préenregistre quelques informations temporaire pour mettre à jour le modèle
        int debut = data.getCaret().getDot();
        int fin = data.getCaret().getMark();
        if ((fin-debut)!=0){
            ctrl.select();
        }
    }//GEN-LAST:event_texteMouseReleased

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel JPanel;
    private javax.swing.JButton btnPlay;
    private javax.swing.JButton btnStart;
    private javax.swing.JButton btnStop;
    private javax.swing.JButton btn_coller;
    private javax.swing.JButton btn_copy;
    private javax.swing.JButton btn_cut;
    private javax.swing.JButton btn_redo;
    private javax.swing.JButton btn_undo;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JTextArea texte;
    // End of variables declaration//GEN-END:variables

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private JDialog aboutBox;

    public void updateGUI() {
        if(data.isMacroEnabled()){
            btnStart.setEnabled(false);
            btnStop.setEnabled(true);
        } else {
            btnStart.setEnabled(true);
            btnStop.setEnabled(false);
        }

        if(ctrl.isListEmpty()){
            btnPlay.setEnabled(false);
        } else { btnPlay.setEnabled(true); }

        data.setBuffer(ctrl.getMBuffer());
        data.setLastChar(ctrl.getMLastCharacter());
        data.setPressePapier(ctrl.getMPressePapier());

        texte.setText(data.getBuffer());
        texte.getCaret().setVisible(true);

        texte.requestFocus();
        data.setCaretPos(ctrl.getMCurrentPos());

        //Buton undo et redo
        if (!ctrl.isUndoable()) btn_undo.setEnabled(false);
        if (!ctrl.isRedoable()) btn_redo.setEnabled(false);

        //Bouton copie
        if(ctrl.isVTextSelected()) btn_copy.setEnabled(true);
        else btn_copy.setEnabled(false);

        //bouton coller
        if(!ctrl.getVPressePapier().equalsIgnoreCase("")) btn_coller.setEnabled(true);
        else btn_coller.setEnabled(false);

        //bouton couper
        if(ctrl.isVTextSelected()) btn_cut.setEnabled(true);
        else btn_cut.setEnabled(false);

        if (ctrl.getMSelect_fin()-ctrl.getMSelect_debut()!=0){
            texte.select(Math.max(0,ctrl.getMSelect_debut()),Math.min(ctrl.getMSelect_fin(),texte.getText().length()));
        }

    }

    /*****************************************************************
     * Updating View
     ******************************************************************/
    public void update_insert() {
        updateGUI();
        btn_undo.setEnabled(true);
    }

    public void update_undo() {
        updateGUI();
        btn_redo.setEnabled(true);
    }

    public void update_redo(){
        updateGUI();
        btn_undo.setEnabled(true);
    }

    public void update_delete() {
        updateGUI();
        btn_undo.setEnabled(true);
    }

    public void update_selection() {
        updateGUI();
    }

    public void update_paste() {
        updateGUI();
    }

    public void update_cut() {
        updateGUI();
    }

    public void updateLastChar(Character c){
        data.setLastChar(c);
    }

    public void update_copy(){
        updateGUI();
    }

    /*****************************************************************
     * Get Temp Data View [GVI]
     ******************************************************************/
    public Character getLastChar() {
        return data.getLastChar();
    }

    public int getPosition_cursor() {
        return texte.getCaret().getDot();
    }

    public String getText() {
        return data.getBuffer();
    }

    public boolean getMacroEnabled(){
        return data.isMacroEnabled();
    }

    public int getSelect_fin() {
        return texte.getCaret().getMark();
    }

    public boolean isTextSelected(){
        return ((ctrl.getMSelect_fin()-ctrl.getMSelect_debut())!=0);
    }

    public String getPressePapier(){
        return data.getPressePapier();
    }
    /********************************************************************
     * Click action command
     ********************************************************************/
    @Action
    public void Undo_click() {
        ctrl.undo();
    }

    @Action
    public void redo_click() {
        ctrl.redo();
    }

    @Action
    public void StopRecord_click() {
        data.setMacroEnabled(false);
        updateGUI();
    }

    @Action
    public void Replay_click() {
        ctrl.rejouer();
    }

    @Action
    public void Cut_click() {
        ctrl.cut();
    }

    @Action
    public void Copy_click() {
        ctrl.copy();
    }

    @Action
    public void Paste_click() {
        ctrl.paste();
    }

}
